package jee.boot.common.basic.result;

import jee.boot.common.basic.ServiceException;
import jee.boot.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 异常统一处理
 */
@RestControllerAdvice
public class ExceptionHandle {
    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);

    @Autowired
    private MessageCodeHelper messageCodeHelper;

    /**
     * (@RequestBody参数)数据校验异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseMessage<Object> methodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        String join = "\r\n" + StringUtils.join(bindingResult.getAllErrors().stream().map(ObjectError::getDefaultMessage), "\r\n");
        return Result.serverError(1307, messageCodeHelper.getMessage(1307, MapData.instance().put("message", join).data(), ""));
    }

    /**
     * (path参数)数据校验异常
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(BindException.class)
    public ResponseMessage<Object> handleBindException(HttpServletRequest request, BindException exception) {
        List<FieldError> allErrors = exception.getFieldErrors();
        String join = "\r\n" + StringUtils.join(allErrors.stream().map(FieldError::getDefaultMessage), "\r\n");
        return Result.serverError(1307, messageCodeHelper.getMessage(1307, MapData.instance().put("message", join).data(), ""));
    }

    /**
     * 业务异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = ServiceException.class)
    public ResponseMessage<Object> serviceException(ServiceException exception) {
        logger.error(exception.getCode() + ": " + exception.getMessage(), exception);
        if (500 == exception.getCode()) {
            return Result.serverError(exception.getCode(), exception.getMessage());
        }
        return Result.serverError(exception.getCode(), messageCodeHelper.getMessage(exception.getCode(), exception.getData(), exception.getMessage()));
    }

    /**
     * 全局异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseMessage<Object> exception(Exception exception) {
        logger.error(exception.getMessage(), exception);
        return Result.serverError(500, messageCodeHelper.getMessage(500, MapData.instance().put("message", exception.getMessage()).data(), exception.getMessage()), exception);
    }


}